package org.kl.bf.service;

import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.joda.time.DateTime;
import org.kl.bf.entity.basic.OperateLogs;
import org.kl.bf.service.basic.OperateLogsService;
import org.kl.bf.web.base.BasicController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * @Author hqm
 * @CreateTime 2014年3月30日 上午10:56:32
 */
public class OperateLogsHandlerIntecepter extends HandlerInterceptorAdapter {
	/**
	 * 免登入 免检查地址
	 */
	private List<String> uncheckUrls;
	private OperateLogsService operateLogsService;

	protected Logger logger = LoggerFactory.getLogger(getClass());
	private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("StopWatch-StartTime");

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		long beginTime = System.currentTimeMillis();// 1、开始时间
		startTimeThreadLocal.set(beginTime);// 线程绑定变量（该数据只有当前请求的线程可见）
		return true;// 继续流程
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		if (handler instanceof HandlerMethod) {
			String requestURL = request.getRequestURI();
			for (String u : uncheckUrls) {
				if (requestURL.indexOf(u) > -1) {
					return;
				}
			}
			OperateLogs ol = new OperateLogs();
			ol.setOperateName(BasicController.getCurrentUserName());
			ol.setOperateIp(request.getRemoteHost());
			ol.setOperateTime(new Timestamp(new DateTime().getMillis()));
			ol.setRequestUrl(requestURL);

			HandlerMethod handlerMethod = (HandlerMethod) handler;
			RequiresPermissions rp = handlerMethod.getMethodAnnotation(RequiresPermissions.class);
			if (rp != null) {
				ol.setShiroRequiresPermissions(Arrays.toString(rp.value()));
			}
			RequestMapping rm = handlerMethod.getBeanType().getAnnotation(RequestMapping.class);
			if (rm != null) {
				ol.setControllerRequestMapping(Arrays.toString(rm.value()));
			}
			rm = handlerMethod.getMethodAnnotation(RequestMapping.class);
			if (rm != null) {
				ol.setMethodRequestMapping(Arrays.toString(rm.value()));
			}
			ol.setExecutionTime(System.currentTimeMillis() - startTimeThreadLocal.get());
			operateLogsService.saveOperateLogs(ol);
		}
	}

	public void setUncheckUrls(List<String> uncheckUrls) {
		this.uncheckUrls = uncheckUrls;
	}

	public void setOperateLogsService(OperateLogsService operateLogsService) {
		this.operateLogsService = operateLogsService;
	}

}
